home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gawk / sprite / awk.h < prev   
Encoding:
C/C++ Source or Header  |  1990-06-28  |  16.3 KB  |  611 lines

  1. /*
  2.  * awk.h -- Definitions for gawk. 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. /* ------------------------------ Includes ------------------------------ */
  27. #include <stdio.h>
  28. #include <ctype.h>
  29. #include <setjmp.h>
  30. #include <varargs.h>
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33. #include <errno.h>
  34.  
  35. #include "regex.h"
  36.  
  37. /* ------------------- System Functions, Variables, etc ------------------- */
  38. /* nasty nasty SunOS-ism */
  39. #ifdef sparc
  40. #include <alloca.h>
  41. #ifdef lint
  42. extern char *alloca();
  43. #endif
  44. #else
  45. extern char *alloca();
  46. #endif
  47. #ifdef SPRINTF_INT
  48. extern int sprintf();
  49. #else    /* not USG */
  50. /* nasty nasty berkelixm */
  51. #define setjmp    _setjmp
  52. #define longjmp    _longjmp
  53.  
  54. extern char *sprintf();
  55. #endif
  56. /*
  57.  * if you don't have vprintf, but you are BSD, the version defined in
  58.  * vprintf.c should do the trick.  Otherwise, use this and cross your fingers.
  59.  */
  60. #if defined(VPRINTF_MISSING) && !defined(DOPRNT_MISSING) && !defined(BSDSTDIO)
  61. #define vfprintf(fp,fmt,arg)    _doprnt((fmt), (arg), (fp))
  62. #endif
  63.  
  64. #ifdef __STDC__
  65. extern void *malloc(unsigned), *realloc(void *, unsigned);
  66. extern void free(char *);
  67. extern char *getenv(char *);
  68.  
  69. extern char *strcpy(char *, char *), *strcat(char *, char *), *strncpy(char *, char *, int);
  70. extern int strcmp(char *, char *);
  71. extern int strncmp(char *, char *, int);
  72. extern int strncasecmp(char *, char *, int);
  73. extern char *strerror(int);
  74. extern char *strchr(char *, int);
  75. extern int strlen(char *);
  76. extern    char *memcpy(char *, char *, int);
  77. extern    int memcmp(char *, char *, int);
  78. extern    char *memset(char *, int, int);
  79.  
  80. /* extern int fprintf(FILE *, char *, ...); */
  81. extern int fprintf();
  82. extern int vfprintf();
  83. #ifndef MSDOS
  84. extern int fwrite(char *, int, int, FILE *);
  85. #endif
  86. extern int fflush(FILE *);
  87. extern int fclose(FILE *);
  88. extern int pclose(FILE *);
  89. #ifndef MSDOS
  90. extern int fputs(char *, FILE *);
  91. #endif
  92. extern void abort();
  93. extern int isatty(int);
  94. extern void exit(int);
  95. extern int system(char *);
  96. extern int sscanf(/* char *, char *, ... */);
  97.  
  98. extern double atof(char *);
  99. extern int fstat(int, struct stat *);
  100. extern off_t lseek(int, off_t, int);
  101. extern long fseek(FILE *, long, int);
  102. extern int close(int);
  103. extern int open();
  104. extern int pipe(int *);
  105. extern int dup2(int, int);
  106. #ifndef MSDOS
  107. extern int unlink(char *);
  108. #endif
  109. extern int fork();
  110. extern int execl(/* char *, char *, ... */);
  111. extern int read(int, char *, int);
  112. extern int wait(int *);
  113. extern void _exit(int);
  114. #else
  115. extern void _exit();
  116. extern int wait();
  117. extern int read();
  118. extern int execl();
  119. extern int fork();
  120. extern int unlink();
  121. extern int dup2();
  122. extern int pipe();
  123. extern int open();
  124. extern int close();
  125. extern int fseek();
  126. extern off_t lseek();
  127. extern int fstat();
  128. extern void exit();
  129. extern int system();
  130. extern int isatty();
  131. extern void abort();
  132. extern int fputs();
  133. extern int fclose();
  134. extern int pclose();
  135. extern int fflush();
  136. extern int fwrite();
  137. extern int fprintf();
  138. extern int vfprintf();
  139. extern int sscanf();
  140. extern char *malloc(), *realloc();
  141. extern void free();
  142. extern char *getenv();
  143.  
  144. extern int strcmp();
  145. extern int strncmp();
  146. extern int strncasecmp();
  147. extern int strlen();
  148. extern char *strcpy(), *strcat(), *strncpy();
  149. extern    char *memset();
  150. extern    int memcmp();
  151. extern    char *memcpy();
  152. extern char *strerror();
  153. extern char *strchr();
  154.  
  155. extern double atof();
  156. #endif
  157.  
  158. #ifndef MSDOS
  159. extern int errno;
  160. #endif    /* MSDOS */
  161.  
  162. /* ------------------ Constants, Structures, Typedefs  ------------------ */
  163. #define AWKNUM    double
  164.  
  165. typedef enum {
  166.     /* illegal entry == 0 */
  167.     Node_illegal,
  168.  
  169.     /* binary operators  lnode and rnode are the expressions to work on */
  170.     Node_times,
  171.     Node_quotient,
  172.     Node_mod,
  173.     Node_plus,
  174.     Node_minus,
  175.     Node_cond_pair,        /* conditional pair (see Node_line_range) */
  176.     Node_subscript,
  177.     Node_concat,
  178.     Node_exp,
  179.  
  180.     /* unary operators   subnode is the expression to work on */
  181. /*10*/    Node_preincrement,
  182.     Node_predecrement,
  183.     Node_postincrement,
  184.     Node_postdecrement,
  185.     Node_unary_minus,
  186.     Node_field_spec,
  187.  
  188.     /* assignments   lnode is the var to assign to, rnode is the exp */
  189.     Node_assign,
  190.     Node_assign_times,
  191.     Node_assign_quotient,
  192.     Node_assign_mod,
  193. /*20*/    Node_assign_plus,
  194.     Node_assign_minus,
  195.     Node_assign_exp,
  196.  
  197.     /* boolean binaries   lnode and rnode are expressions */
  198.     Node_and,
  199.     Node_or,
  200.  
  201.     /* binary relationals   compares lnode and rnode */
  202.     Node_equal,
  203.     Node_notequal,
  204.     Node_less,
  205.     Node_greater,
  206.     Node_leq,
  207. /*30*/    Node_geq,
  208.     Node_match,
  209.     Node_nomatch,
  210.  
  211.     /* unary relationals   works on subnode */
  212.     Node_not,
  213.  
  214.     /* program structures */
  215.     Node_rule_list,        /* lnode is a rule, rnode is rest of list */
  216.     Node_rule_node,        /* lnode is pattern, rnode is statement */
  217.     Node_statement_list,    /* lnode is statement, rnode is more list */
  218.     Node_if_branches,    /* lnode is to run on true, rnode on false */
  219.     Node_expression_list,    /* lnode is an exp, rnode is more list */
  220.     Node_param_list,    /* lnode is a variable, rnode is more list */
  221.  
  222.     /* keywords */
  223. /*40*/    Node_K_if,        /* lnode is conditonal, rnode is if_branches */
  224.     Node_K_while,        /* lnode is condtional, rnode is stuff to run */
  225.     Node_K_for,        /* lnode is for_struct, rnode is stuff to run */
  226.     Node_K_arrayfor,    /* lnode is for_struct, rnode is stuff to run */
  227.     Node_K_break,        /* no subs */
  228.     Node_K_continue,    /* no stuff */
  229.     Node_K_print,        /* lnode is exp_list, rnode is redirect */
  230.     Node_K_printf,        /* lnode is exp_list, rnode is redirect */
  231.     Node_K_next,        /* no subs */
  232.     Node_K_exit,        /* subnode is return value, or NULL */
  233.     Node_K_do,        /* lnode is conditional, rnode stuff to run */
  234.     Node_K_return,
  235.     Node_K_delete,
  236.     Node_K_getline,
  237.     Node_K_function,    /* lnode is statement list, rnode is params */
  238.  
  239.     /* I/O redirection for print statements */
  240.     Node_redirect_output,    /* subnode is where to redirect */
  241.     Node_redirect_append,    /* subnode is where to redirect */
  242.     Node_redirect_pipe,    /* subnode is where to redirect */
  243.     Node_redirect_pipein,    /* subnode is where to redirect */
  244.     Node_redirect_input,    /* subnode is where to redirect */
  245.  
  246.     /* Variables */
  247.     Node_var,        /* rnode is value, lnode is array stuff */
  248.     Node_var_array,        /* array is ptr to elements, asize num of
  249.                  * eles */
  250.     Node_val,        /* node is a value - type in flags */
  251.  
  252.     /* Builtins   subnode is explist to work on, proc is func to call */
  253.     Node_builtin,
  254.  
  255.     /*
  256.      * pattern: conditional ',' conditional ;  lnode of Node_line_range
  257.      * is the two conditionals (Node_cond_pair), other word (rnode place)
  258.      * is a flag indicating whether or not this range has been entered.
  259.      */
  260.     Node_line_range,
  261.  
  262.     /*
  263.      * boolean test of membership in array lnode is string-valued
  264.      * expression rnode is array name 
  265.      */
  266.     Node_in_array,
  267.  
  268.     Node_func,        /* lnode is param. list, rnode is body */
  269.     Node_func_call,        /* lnode is name, rnode is argument list */
  270.  
  271.     Node_cond_exp,        /* lnode is conditonal, rnode is if_branches */
  272.     Node_regex,
  273.     Node_hashnode,
  274.     Node_ahash,
  275. } NODETYPE;
  276.  
  277. /*
  278.  * NOTE - this struct is a rather kludgey -- it is packed to minimize
  279.  * space usage, at the expense of cleanliness.  Alter at own risk.
  280.  */
  281. typedef struct exp_node {
  282.     union {
  283.         struct {
  284.             union {
  285.                 struct exp_node *lptr;
  286.                 char *param_name;
  287.                 char *retext;
  288.                 struct exp_node *nextnode;
  289.             } l;
  290.             union {
  291.                 struct exp_node *rptr;
  292.                 struct exp_node *(*pptr) ();
  293.                 struct re_pattern_buffer *preg;
  294.                 struct for_loop_header *hd;
  295.                 struct exp_node **av;
  296.                 int r_ent;    /* range entered */
  297.             } r;
  298.             char *name;
  299.             short number;
  300.             unsigned char recase;
  301.         } nodep;
  302.         struct {
  303.             AWKNUM fltnum;    /* this is here for optimal packing of
  304.                      * the structure on many machines
  305.                      */
  306.             char *sp;
  307.             short slen;
  308.             unsigned char sref;
  309.         } val;
  310.         struct {
  311.             struct exp_node *next;
  312.             char *name;
  313.             int length;
  314.             struct exp_node *value;
  315.         } hash;
  316. #define    hnext    sub.hash.next
  317. #define    hname    sub.hash.name
  318. #define    hlength    sub.hash.length
  319. #define    hvalue    sub.hash.value
  320.         struct {
  321.             struct exp_node *next;
  322.             struct exp_node *name;
  323.             struct exp_node *value;
  324.         } ahash;
  325. #define    ahnext    sub.ahash.next
  326. #define    ahname    sub.ahash.name
  327. #define    ahvalue    sub.ahash.value
  328.     } sub;
  329.     NODETYPE type;
  330.     unsigned char flags;
  331. #            define    MEM    0x7
  332. #            define    MALLOC    1    /* can be free'd */
  333. #            define    TEMP    2    /* should be free'd */
  334. #            define    PERM    4    /* can't be free'd */
  335. #            define    VAL    0x18
  336. #            define    NUM    8    /* numeric value is valid */
  337. #            define    STR    16    /* string value is valid */
  338. #            define    NUMERIC    32    /* entire field is numeric */
  339. } NODE;
  340.  
  341. #define lnode    sub.nodep.l.lptr
  342. #define nextp    sub.nodep.l.nextnode
  343. #define rnode    sub.nodep.r.rptr
  344. #define source_file    sub.nodep.name
  345. #define    source_line    sub.nodep.number
  346. #define    param_cnt    sub.nodep.number
  347. #define param    sub.nodep.l.param_name
  348.  
  349. #define subnode    lnode
  350. #define proc    sub.nodep.r.pptr
  351.  
  352. #define reexp    lnode
  353. #define rereg    sub.nodep.r.preg
  354. #define re_case sub.nodep.recase
  355. #define re_text sub.nodep.l.retext
  356.  
  357. #define forsub    lnode
  358. #define forloop    rnode->sub.nodep.r.hd
  359.  
  360. #define stptr    sub.val.sp
  361. #define stlen    sub.val.slen
  362. #define stref    sub.val.sref
  363. #define    valstat    flags
  364.  
  365. #define numbr    sub.val.fltnum
  366.  
  367. #define var_value lnode
  368. #define var_array sub.nodep.r.av
  369.  
  370. #define condpair lnode
  371. #define triggered sub.nodep.r.r_ent
  372.  
  373. #define HASHSIZE 101
  374.  
  375. typedef struct for_loop_header {
  376.     NODE *init;
  377.     NODE *cond;
  378.     NODE *incr;
  379. } FOR_LOOP_HEADER;
  380.  
  381. /* for "for(iggy in foo) {" */
  382. struct search {
  383.     int numleft;
  384.     NODE **arr_ptr;
  385.     NODE *bucket;
  386.     NODE *retval;
  387. };
  388.  
  389. /* for faster input, bypass stdio */
  390. typedef struct iobuf {
  391.     int fd;
  392.     char *buf;
  393.     char *off;
  394.     int size;    /* this will be determined by an fstat() call */
  395.     int cnt;
  396.     char *secbuf;
  397.     int secsiz;
  398.     int flag;
  399. #    define        IOP_IS_TTY    1
  400. } IOBUF;
  401.  
  402. /*
  403.  * structure used to dynamically maintain a linked-list of open files/pipes
  404.  */
  405. struct redirect {
  406.     int flag;
  407. #        define        RED_FILE    1
  408. #        define        RED_PIPE    2
  409. #        define        RED_READ    4
  410. #        define        RED_WRITE    8
  411. #        define        RED_APPEND    16
  412. #        define        RED_NOBUF    32
  413.     char *value;
  414.     FILE *fp;
  415.     IOBUF *iop;
  416.     int pid;
  417.     int status;
  418.     long offset;        /* used for dynamic management of open files */
  419.     struct redirect *prev;
  420.     struct redirect *next;
  421. };
  422.  
  423. /* longjmp return codes, must be nonzero */
  424. /* Continue means either for loop/while continue, or next input record */
  425. #define TAG_CONTINUE 1
  426. /* Break means either for/while break, or stop reading input */
  427. #define TAG_BREAK 2
  428. /* Return means return from a function call; leave value in ret_node */
  429. #define    TAG_RETURN 3
  430.  
  431. #ifdef MSDOS
  432. #define HUGE    0x7fff
  433. #else
  434. #define HUGE    0x7fffffff
  435. #endif
  436.  
  437. /* -------------------------- External variables -------------------------- */
  438. /* gawk builtin variables */
  439. extern NODE *FS_node, *NF_node, *RS_node, *NR_node;
  440. extern NODE *FILENAME_node, *OFS_node, *ORS_node, *OFMT_node;
  441. extern NODE *FNR_node, *RLENGTH_node, *RSTART_node, *SUBSEP_node;
  442. extern NODE *IGNORECASE_node;
  443.  
  444. extern NODE **stack_ptr;
  445. extern NODE *Nnull_string;
  446. extern NODE *deref;
  447. extern NODE **fields_arr;
  448. extern int sourceline;
  449. extern char *source;
  450. extern NODE *expression_value;
  451.  
  452. extern NODE *variables[];
  453.  
  454. extern NODE *_t;    /* used as temporary in tree_eval */
  455.  
  456. extern char *myname;
  457.  
  458. extern int node0_valid;
  459. extern int field_num;
  460. extern int strict;
  461.  
  462. /* ------------------------- Pseudo-functions ------------------------- */
  463. #define is_identchar(c) (isalnum(c) || (c) == '_')
  464.  
  465.  
  466. #define    free_temp(n)    if ((n)->flags&TEMP) { deref = (n); do_deref(); } else
  467. #define    tree_eval(t)    (_t = (t),(_t) == NULL ? Nnull_string : \
  468.             ((_t)->type == Node_val ? (_t) : r_tree_eval((_t))))
  469. #define    make_string(s,l)    make_str_node((s),(l),0)
  470.  
  471. #define    cant_happen()    fatal("line %d, file: %s; bailing out", \
  472.                 __LINE__, __FILE__);
  473. #ifdef MEMDEBUG
  474. #define memmsg(x,y,z,zz)    fprintf(stderr, "malloc: %s: %s: %d %0x\n", z, x, y, zz)
  475. #define free(s)    fprintf(stderr, "free: s: %0x\n", s), do_free(s)
  476. #else
  477. #define memmsg(x,y,z,zz)
  478. #endif
  479.  
  480. #define    emalloc(var,ty,x,str)    if ((var = (ty) malloc((unsigned)(x))) == NULL)\
  481.                     fatal("%s: %s: can't allocate memory (%s)",\
  482.                     (str), "var", strerror(errno)); else\
  483.                     memmsg("var", x, str, var)
  484. #define    erealloc(var,ty,x,str)    if((var=(ty)realloc((char *)var,\
  485.                         (unsigned)(x)))==NULL)\
  486.                     fatal("%s: %s: can't allocate memory (%s)",\
  487.                     (str), "var", strerror(errno)); else\
  488.                     memmsg("re: var", x, str, var)
  489. #ifdef DEBUG
  490. #define    force_number    r_force_number
  491. #define    force_string    r_force_string
  492. #else
  493. #ifdef lint
  494. extern AWKNUM force_number();
  495. #endif
  496. #ifdef MSDOS
  497. extern double _msc51bug;
  498. #define    force_number(n)    (_msc51bug=(_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t)))
  499. #else
  500. #define    force_number(n)    (_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t))
  501. #endif
  502. #define    force_string(s)    (_t = (s),(_t->flags & STR) ? _t : r_force_string(_t))
  503. #endif
  504.  
  505. #define    STREQ(a,b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  506. #define    STREQN(a,b,n)    ((n) && *(a) == *(b) && strncmp((a), (b), (n)) == 0)
  507.  
  508. #define    WHOLELINE    (node0_valid ? fields_arr[0] : *get_field(0,0))
  509.  
  510. /* ------------- Function prototypes or defs (as appropriate) ------------- */
  511. #ifdef __STDC__
  512. extern    int parse_escape(char **);
  513. extern    int devopen(char *, char *);
  514. extern    struct re_pattern_buffer *make_regexp(NODE *, int);
  515. extern    struct re_pattern_buffer *mk_re_parse(char *, int);
  516. extern    NODE *variable(char *);
  517. extern    NODE *install(NODE **, char *, NODE *);
  518. extern    NODE *lookup(NODE **, char *);
  519. extern    NODE *make_name(char *, NODETYPE);
  520. extern    int interpret(NODE *);
  521. extern    NODE *r_tree_eval(NODE *);
  522. extern    void assign_number(NODE **, double);
  523. extern    int cmp_nodes(NODE *, NODE *);
  524. extern    struct redirect *redirect(NODE *, int *);
  525. extern    int flush_io(void);
  526. extern    void print_simple(NODE *, FILE *);
  527. /* extern    void warning(char *,...); */
  528. extern    void warning();
  529. /* extern    void fatal(char *,...); */
  530. extern    void fatal();
  531. extern    void set_record(char *, int);
  532. extern    NODE **get_field(int, int);
  533. extern    NODE **get_lhs(NODE *, int);
  534. extern    void do_deref(void );
  535. extern    struct search *assoc_scan(NODE *);
  536. extern    struct search *assoc_next(struct search *);
  537. extern    NODE **assoc_lookup(NODE *, NODE *);
  538. extern    double r_force_number(NODE *);
  539. extern    NODE *r_force_string(NODE *);
  540. extern    NODE *newnode(NODETYPE);
  541. extern    NODE *dupnode(NODE *);
  542. extern    NODE *make_number(double);
  543. extern    NODE *tmp_number(double);
  544. extern    NODE *make_str_node(char *, int, int);
  545. extern    NODE *tmp_string(char *, int);
  546. extern    char *re_compile_pattern(char *, int, struct re_pattern_buffer *);
  547. extern    int re_search(struct re_pattern_buffer *, char *, int, int, int, struct re_registers *);
  548. extern    void freenode(NODE *);
  549.  
  550. #else
  551. extern    int parse_escape();
  552. extern    void freenode();
  553. extern    int devopen();
  554. extern    struct re_pattern_buffer *make_regexp();
  555. extern    struct re_pattern_buffer *mk_re_parse();
  556. extern    NODE *variable();
  557. extern    NODE *install();
  558. extern    NODE *lookup();
  559. extern    int interpret();
  560. extern    NODE *r_tree_eval();
  561. extern    void assign_number();
  562. extern    int cmp_nodes();
  563. extern    struct redirect *redirect();
  564. extern    int flush_io();
  565. extern    void print_simple();
  566. extern    void warning();
  567. extern    void fatal();
  568. extern    void set_record();
  569. extern    NODE **get_field();
  570. extern    NODE **get_lhs();
  571. extern    void do_deref();
  572. extern    struct search *assoc_scan();
  573. extern    struct search *assoc_next();
  574. extern    NODE **assoc_lookup();
  575. extern    double r_force_number();
  576. extern    NODE *r_force_string();
  577. extern    NODE *newnode();
  578. extern    NODE *dupnode();
  579. extern    NODE *make_number();
  580. extern    NODE *tmp_number();
  581. extern    NODE *make_str_node();
  582. extern    NODE *tmp_string();
  583. extern    char *re_compile_pattern();
  584. extern    int re_search();
  585. #endif
  586.  
  587. #if !defined(__STDC__) || __STDC__ <= 0
  588. #define volatile
  589. #endif
  590.  
  591. /* Figure out what '\a' really is. */
  592. #ifdef __STDC__
  593. #define BELL    '\a'        /* sure makes life easy, don't it? */
  594. #else
  595. #    if 'z' - 'a' == 25    /* ascii */
  596. #        if 'a' != 97    /* machine is dumb enough to use mark parity */
  597. #            define BELL    '\207'
  598. #        else
  599. #            define BELL    '\07'
  600. #        endif
  601. #    else
  602. #        define BELL    '\057'
  603. #    endif
  604. #endif
  605.  
  606. #ifndef SIGTYPE
  607. #define SIGTYPE    void
  608. #endif
  609.  
  610. extern char casetable[];    /* for case-independent regexp matching */
  611.